import { getCreepWorking } from '@/utils/common'
import { UpgradeMemory } from './types'
import { goTo } from '@/modules/move'

/**
 * upgradeCarrier 工作函数
 */
export const upgradeCarrierWork = function (room: MyRoom, upgradeCarriers: Creep[], upgradeMemory: UpgradeMemory) {
    const creeps = upgradeCarriers.filter((creep) => !creep.spawning)
    if (!creeps.length) return

    creeps.forEach((creep) => {
        if (creep.memory.slack) {
            return
        }
        getCreepWorking(creep)

        if (creep.ticksToLive! < 30 && creep.store.getUsedCapacity() === 0) {
            creep.suicide()
        }

        if (creep.memory.working) {
            if (!creep.memory.targetId) {
                const upgradeContainers = upgradeMemory.containerIds
                    .map((id) => Game.getObjectById(id))
                    .filter((s) => s && s.store.getFreeCapacity('energy') > 300) as StructureContainer[]
                const target = _.min(upgradeContainers, (s) => s.store['energy'])
                if (target) creep.memory.targetId = target.id
                else {
                    creep.memory.slack = _.random(10, 20)
                    return
                }
            }

            const target = Game.getObjectById(creep.memory.targetId as Id<StructureContainer>)

            if (!target || target.store.getFreeCapacity('energy') < 150) {
                delete creep.memory.targetId
                return
            }

            if (creep.transfer(target, 'energy') === ERR_NOT_IN_RANGE) {
                goTo(creep, target.pos)
            }
        } else {
            if (!creep.memory.sourceId) {
                if (room.storage && room.storage.store['energy'] > 2000) {
                    creep.memory.sourceId = room.storage.id
                } else if (room.terminal && room.terminal.store['energy'] > 2000) {
                    creep.memory.sourceId = room.terminal.id
                } else {
                    // 优先选择能量最多的container
                    const sourceContainers = Object.values(room.memory.source)
                        .map(({ containerId }) => containerId && Game.getObjectById(containerId))
                        .filter((s) => s && s.store['energy'] > 1200) as StructureContainer[]
                    if (sourceContainers.length) {
                        creep.memory.sourceId = _.max(sourceContainers, (s) => s.store['energy'])?.id
                    }
                }
            }

            if (!creep.memory.sourceId) {
                creep.memory.slack = _.random(5, 10)
            }

            const source = Game.getObjectById(creep.memory.sourceId as Id<AnyStoreStructure>)

            if (!source || source.store['energy'] < 400) {
                delete creep.memory.sourceId
                return
            }

            if (creep.withdraw(source, 'energy') === ERR_NOT_IN_RANGE) {
                goTo(creep, source.pos)
            }
        }
    })
}
